package cn.tianjindong.blog_portal.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;

import cn.tianjindong.blog.common.utils.CookieUtils;
import cn.tianjindong.blog.common.utils.MD5Utils;
import cn.tianjindong.blog.common.utils.VisiterInfoUtils;
import cn.tianjindong.blog.pojo.BlogUser;
import cn.tianjindong.blog_portal.service.UserService;

/**
 * 账户相关功能（登录、注册、激活等）
 * 
 * @author 田 金 东
 *
 */
@Controller
public class AccountController {
	@Autowired
	private UserService userService;

	/**
	 * 上一次访问的需要调用的页面
	 */
	private static final String REQUEST_URL = "requestUrl";
	/**
	 * session中保存的验证码的key
	 */
	private static final String CHECK_CODE = "checkCode";
	/**
	 * 验证码错误，重定向时携带的username的key
	 */
	private static final String USERNAME = "username";
	/**
	 * 验证码错误，重定向时携带的password的key
	 */
	private static final String PASSWORD = "password";
	/**
	 * 返回登录校验失败的原因的key
	 */
	private static final String ERROR = "error";
	/**
	 * 用户对象保存在session中key
	 */
	private static final String USER = "user";
	/**
	 * 验证码错误
	 */
	private static final String CHECK_CODE_ERROR = "checkCodeError";
	/**
	 * 账户未激活错误
	 */
	private static final String UN_ACTIVATION_ERROR = "unActivationError";
	/**
	 * 账户处于作废状态
	 */
	private static final String USELESS_ERROR = "uselessError";
	/**
	 * 用户名或密码错误
	 */
	private static final String AUTH_ERROR = "AuthError";

	/**
	 * 跳转登录页面
	 * 
	 * @return
	 */
	@RequestMapping("/login.html")
	public String toLoginPage() {
		return "/login";
	}

	/**
	 * 用户登录操作
	 * 
	 * @param username
	 *            用户名（可以是邮箱，也可以是用户名）
	 * @param password
	 *            密码
	 * @param checkCode
	 *            验证码
	 * @return
	 */
	@RequestMapping("/account/login.action")
	public String login(Model model, HttpSession session, HttpServletRequest request, HttpServletResponse response,
			@RequestParam(required = true) String username, @RequestParam(required = true) String password,
			@RequestParam(required = true) String checkCode) {
		String url = null;
		url = CookieUtils.getCookieValue(request, REQUEST_URL);// 获取Cookie中登记的原先访问的页面，登录完成后跳转到这个页面中去
		CookieUtils.deleteCookie(request, response, REQUEST_URL);

		String code = (String) session.getAttribute(CHECK_CODE);
		session.removeAttribute(CHECK_CODE);// 登录操作后移除验证码信息
		String passwd = MD5Utils.md5(password);
		if (code == null || !code.equals(checkCode.toLowerCase())) {// 校验 验证码
			session.removeAttribute(CHECK_CODE);
			model.addAttribute(USERNAME, username);
			model.addAttribute(PASSWORD, password);
			model.addAttribute(ERROR, CHECK_CODE_ERROR);
			return "/login";
		}
		BlogUser user = userService.selectByUsernameOrEmail(username);
		if (user != null && user.getActivation() == 0) {// 账户未激活
			model.addAttribute(ERROR, UN_ACTIVATION_ERROR);
			model.addAttribute(USERNAME, username);
			model.addAttribute(PASSWORD, password);
			return "/login";
		}
		if (user != null && user.getActivation() == -1) {// 账户禁用
			model.addAttribute(ERROR, USELESS_ERROR);
			model.addAttribute(USERNAME, username);
			model.addAttribute(PASSWORD, password);
			return "/login";
		}
		if (user == null || !user.getPassword().equals(passwd)) {
			model.addAttribute(ERROR, AUTH_ERROR);// 验证(用户名或密码错误)错误
			return "/login";
		}
		// 记录用户的登录记录
		userService.addVisitLog(user.getId(), VisiterInfoUtils.getIpAddress(request));
		session.setAttribute(USER, user);
		if (url != null) {// 如果cookie中携带了原先的请求路径
			return "redirect:" + url;
		}
		return "redirect:/index.html";
	}

	/**
	 * 跳转注册页面
	 * 
	 * @return
	 */
	@RequestMapping("/register.html")
	public String toRegisterPage() {
		return "/register";
	}

	/**
	 * 处理Ajax请求，校验用户输入的用户名是否存在
	 * 
	 * @return
	 */
	@RequestMapping("/account/regist/checkUsername.action")
	public @ResponseBody String checkUsernameExist(String username) {
		boolean isExist = userService.checkUsername(username);
		Map<String, Boolean> map = new HashMap<>();
		map.put("isExist", isExist);
		return JSON.toJSONString(map);
	}

	/**
	 * 处理Ajax请求，校验用户输入的邮箱是否已经存在
	 * 
	 * @return
	 */
	@RequestMapping("/account/regist/checkEmail.action")
	public @ResponseBody String checkEmailExist(String email) {
		boolean isExist = userService.checkEmail(email);
		Map<String, Boolean> map = new HashMap();
		map.put("isExist", isExist);
		return JSON.toJSONString(map);
	}

	/**
	 * 用户注册操作
	 * 
	 * @param session
	 * @param model
	 * @param user
	 * @param checkCode
	 * @return
	 */
	@RequestMapping("/account/register.action")
	public String register(HttpSession session, Model model, BlogUser user, String checkCode) {
		String code = (String) session.getAttribute("checkCode");
		session.removeAttribute(CHECK_CODE);// 登录操作后移除验证码信息
		String originalPasswd = user.getPassword();
		String passwd = MD5Utils.md5(originalPasswd);
		if (code == null || !code.equals(checkCode)) {// 校验 验证码
			session.removeAttribute(CHECK_CODE);
			model.addAttribute(USERNAME, user.getUsername());
			model.addAttribute("email", user.getEmail());
			model.addAttribute(PASSWORD, originalPasswd);
			model.addAttribute(ERROR, CHECK_CODE_ERROR);
			return "/register";
		}
		user.setPassword(passwd);// 设置加密后的密码
		userService.createAccount(user);
		model.addAttribute(USERNAME, user.getUsername());
		model.addAttribute(PASSWORD, originalPasswd);
		model.addAttribute("promptMessage", user.getEmail());// 跳转登录页面，提示激活后登录
		return "/login";
	}

	/**
	 * 账户激活操作
	 * 
	 * @param userId
	 * @param activationCode
	 * @return
	 */
	@RequestMapping("/account/activation/{userId}/{activationCode}.action")
	public String activation(@PathVariable Long userId, @PathVariable String activationCode) {
		int status = userService.activateAccount(userId, activationCode);
		if (status == 0) {
			return "/activate-account";
		}
		return "/404";
	}

	@RequestMapping("/account/logout.action")
	public @ResponseBody String logout(HttpSession session) {
		session.setAttribute(USER, null);
		return "{\"status\":\"ok\"}";
	}
}
